package com.yape.webCrawler;

import com.alibaba.fastjson2.JSON;
import com.yape.dao.*;
import com.yape.po.*;
import com.yape.webSocket.FastNewsWebSocketHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * @author yape
 * @description 爬虫数据入库服务
 * @date 2025/5/25
 */
@Slf4j
@Repository
public class CrawlerDataService {
    
    @Resource
    private IChinaIndexDao chinaIndexDao;
    
    @Resource
    private ISectorFundFlowDao sectorFundFlowDao;
    
    @Resource
    private IHsgtFundFlowDao hsgtFundFlowDao;
    
    @Resource
    private INewStockDao newStockListingDao;
    
    @Resource
    private IStockNewsDao stockNewsDao;

    @Resource
    private FastNewsWebSocketHandler webSocketHandler;
    
    /**
     * 根据爬虫名称和数据类型，将数据入库
     * @param crawlerName 爬虫名称
     * @param data 爬虫返回的数据
     * @return 入库条数
     */
    @Transactional
    public int saveData(String crawlerName, Object data) {
        if (data == null) {
            log.warn("爬虫[{}]返回数据为空，跳过入库", crawlerName);
            return 0;
        }
        
        int savedCount = 0;
        
        try {
            switch (crawlerName) {
                case "chinaIndex":
                    savedCount = saveChinaIndexData((List<ChinaIndex>) data);
                    break;
                case "sectorFundFlow":
                    savedCount = saveSectorFundFlowData((List<SectorFundFlow>) data);
                    break;
                case "szhkConnect":
                    savedCount = saveHsgtFundFlowData((List<HsgtFundFlow>) data);
                    break;
                case "newStock":
                    savedCount = saveNewStockListingData((List<NewStockListing>) data);
                    break;
                case "fastNews":
                    savedCount = saveStockNewsData((List<StockNews>) data);
                    break;
                case "newsCount":
                    // 快讯数量不需要入库，只是统计信息
                    log.info("快讯数量统计：{}", data);
                    break;
                default:
                    log.warn("未知的爬虫类型：{}", crawlerName);
            }
            
            log.info("爬虫[{}]数据入库完成，共{}条", crawlerName, savedCount);
            
        } catch (Exception e) {
            log.error("爬虫[{}]数据入库失败：{}", crawlerName, e.getMessage(), e);
            throw e; // 重新抛出异常，触发事务回滚
        }
        
        return savedCount;
    }
    
    private int saveChinaIndexData(List<ChinaIndex> indexList) {
        if (indexList == null || indexList.isEmpty()) {
            return 0;
        }
        
        // 清空当日数据，避免重复
        chinaIndexDao.clearTodayData();
        
        return chinaIndexDao.batchInsert(indexList);
    }
    
    private int saveSectorFundFlowData(List<SectorFundFlow> sectorList) {
        if (sectorList == null || sectorList.isEmpty()) {
            return 0;
        }
        
        sectorFundFlowDao.clearTodayData();
        return sectorFundFlowDao.batchInsert(sectorList);
    }
    
    private int saveHsgtFundFlowData(List<HsgtFundFlow> hsgtList) {
        if (hsgtList == null || hsgtList.isEmpty()) {
            return 0;
        }
        
        hsgtFundFlowDao.clearTodayData();
        return hsgtFundFlowDao.batchInsert(hsgtList);
    }
    
    private int saveNewStockListingData(List<NewStockListing> stockList) {
        if (stockList == null || stockList.isEmpty()) {
            return 0;
        }
        
        // 清理旧数据（保留最近一周）
        newStockListingDao.clearTodayData();
        return newStockListingDao.batchInsert(stockList);
    }
    
    private int saveStockNewsData(List<StockNews> newsList) {
        if (newsList == null || newsList.isEmpty()) {
            return 0;
        }

        // 1. 查询库中最新快讯的 publish_time
        StockNews latestNews = stockNewsDao.selectLatestNews();
        String latestPublishTime = latestNews != null ? latestNews.getPublishTime() : null;

        // 2. 过滤出比库中最新快讯更新的快讯
        List<StockNews> newNewsList = new ArrayList<>();
        for (StockNews news : newsList) {
            if (latestPublishTime == null || news.getPublishTime().compareTo(latestPublishTime) > 0) {
                newNewsList.add(news);
            }
        }

        if (newNewsList.isEmpty()) {
            return 0;
        }
        // 3. 按publish_time升序排序，保证插入时id递增
        newNewsList.sort(Comparator.comparing(StockNews::getPublishTime));
        // 5. 推送到前端
        String json = JSON.toJSONString(newNewsList);
        webSocketHandler.broadcast(json);
        // 3. 只插入新增快讯
        return stockNewsDao.batchInsert(newNewsList);
    }
}